/*
 * Famon (http://code.google.com/p/famon/)
 * Copyright (c) 2010 Carl Crous.
 *
 * This file is part of Famon.
 *
 * Famon is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Famon is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Famon.  If not, see <http://www.gnu.org/licenses/>.
 */

package za.org.foobar.famon.frontend.server.data;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gwtportlets.portlet.smartgwt.client.DataTransferObject;
import org.gwtportlets.portlet.smartgwt.client.SmartPortletFactory;
import org.gwtportlets.portlet.smartgwt.server.DataProviderObject;
import org.gwtportlets.portlet.smartgwt.server.SmartFilter;
import za.org.foobar.famon.frontend.client.dto.ApplicationTreeDto;
import za.org.foobar.famon.frontend.server.ApplicationLogic;
import za.org.foobar.famon.model.Application;
import za.org.foobar.famon.model.ApplicationInstance;
import za.org.foobar.famon.model.ApplicationUser;
import za.org.foobar.famon.model.ApplicationVersion;
import za.org.foobar.famon.util.DB;

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class ApplicationTreeDpo implements DataProviderObject {
    public final Log log = LogFactory.getLog(getClass());
    private static final String OPT_INSTANCES = "Instances";
    private static final String OPT_VERSIONS = "Versions";
    private static final String OPT_USERS = "Users";
    private final ApplicationLogic applicationLogic;

    public ApplicationTreeDpo() {
        applicationLogic = ApplicationLogic.get();
    }

    public String getDataSourceId() {
        return ApplicationTreeDto.DATA_SOURCE_ID;
    }

    public List<DataTransferObject> fetchData(SmartPortletFactory f) {
        log.info("Fetch Data");
        log.info("Criteria: " + f.getCriteria());
        String parentKey = SmartFilter.getSimpleCriteriaValue(f.getCriteria(), "parentKey");
        List<ApplicationTreeDto> list = new ArrayList<ApplicationTreeDto>();
        if (parentKey == null) {
            List<Application> appList = applicationLogic.getApplicationList();
            for (Application app : appList) {
                list.add(createApplicationTreeDto(app));
            }
        } else if (parentKey.startsWith(ApplicationTreeDto.Type.USER.name())) {

        } else {
            String option = null;
            if (parentKey.startsWith(ApplicationTreeDto.Type.OPTION.name())) {
                int i = ApplicationTreeDto.Type.OPTION.name().length() + 1;
                int j = parentKey.indexOf('_', i+1);
                if (j > i) {
                    option = parentKey.substring(i, j);
                }
                parentKey = parentKey.substring(j+1);
            }
            Key key = KeyFactory.stringToKey(parentKey);
            if (key.getKind().equals(Application.class.getSimpleName())) {
                Application app = DB.find(Application.class, key);
                if (option == null) {
                    list.add(createApplicationTreeDto(app, OPT_INSTANCES));
                    list.add(createApplicationTreeDto(app, OPT_VERSIONS));
                    list.add(createApplicationTreeDto(app, OPT_USERS));
                } else if (option.equals(OPT_INSTANCES)) {
                    List<ApplicationInstance> instanceList = app.getInstanceList();
                    for (ApplicationInstance instance : instanceList) {
                        list.add(createApplicationTreeDto(app, instance));
                    }
                } else if (option.equals(OPT_VERSIONS)) {
                    List<ApplicationVersion> versionList = app.getVersionList();
                    for (ApplicationVersion version : versionList) {
                        list.add(createApplicationTreeDto(app, version));
                    }
                } else if (option.equals(OPT_USERS)) {
                    List<ApplicationUser> applicationUserList = app.getUserList();
                    log.info("Got " + applicationUserList.size() + " users");
                    for (ApplicationUser applicationUser : applicationUserList) {
                        list.add(createApplicationTreeDto(app, applicationUser));
                    }
                }
            } else if (key.getKind().equals(ApplicationInstance.class.getSimpleName())) {
            } else if (key.getKind().equals(ApplicationVersion.class.getSimpleName())) {
            }
        }
        log.info("Returning " + list.size() + " objects");
        return f.limitList(list);
    }

    private ApplicationTreeDto createApplicationTreeDto(Application app) {
        ApplicationTreeDto dto = new ApplicationTreeDto();
        dto.type = ApplicationTreeDto.Type.APPLICATION;
        dto.key = KeyFactory.keyToString(app.getId());
        dto.id = app.keyToString();
        dto.name = app.getName();
        dto.canEdit = applicationLogic.canEditApplication(app);
        return dto;
    }

    private ApplicationTreeDto createApplicationTreeDto(Application app, String option) {
        ApplicationTreeDto dto = new ApplicationTreeDto();
        dto.type = ApplicationTreeDto.Type.OPTION;
        dto.key = dto.type + "_" + option + "_" + KeyFactory.keyToString(app.getId());
        dto.name = option;
        dto.canEdit = applicationLogic.canEditApplication(app);
        return dto;
    }

    private ApplicationTreeDto createApplicationTreeDto(Application app, ApplicationInstance instance) {
        ApplicationTreeDto dto = new ApplicationTreeDto();
        dto.type = ApplicationTreeDto.Type.INSTANCE;
        dto.key = KeyFactory.keyToString(instance.getId());
        dto.name = instance.getName();
        dto.canEdit = applicationLogic.canEditApplication(app);
        return dto;
    }

    private ApplicationTreeDto createApplicationTreeDto(Application app, ApplicationVersion version) {
        ApplicationTreeDto dto = new ApplicationTreeDto();
        dto.type = ApplicationTreeDto.Type.VERSION;
        dto.key = KeyFactory.keyToString(version.getId());
        dto.name = version.getName();
        dto.canEdit = applicationLogic.canEditApplication(app);
        return dto;
    }

    private ApplicationTreeDto createApplicationTreeDto(Application app, ApplicationUser applicationUser) {
        ApplicationTreeDto dto = new ApplicationTreeDto();
        dto.type = ApplicationTreeDto.Type.USER;
        dto.key = KeyFactory.keyToString(applicationUser.getId());
        dto.id = applicationUser.keyToString();
        dto.name = applicationUser.getUser().getNickname();
        dto.canEdit = applicationLogic.canEditApplication(app);
        return dto;
    }

    public DataTransferObject updateData(SmartPortletFactory f) {
        return null;
    }

    public DataTransferObject addData(SmartPortletFactory f) {
        return null;
    }

    public DataTransferObject removeData(SmartPortletFactory f) {
        return null;
    }
}
